﻿using System;
using System.Data;
using SD.LLBLGen.Pro.ORMSupportClasses;
using SD.LLBLGen.Pro.QuerySpec;
using SD.LLBLGen.Pro.QuerySpec.Adapter;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using VNet.VisiSuite.Dal.DatabaseSpecific;
using VNet.VisiSuite.Dal.EntityClasses;
using VNet.VisiSuite.Dal.FactoryClasses;
using VNet.VisiSuite.Dal.HelperClasses;
using VNet.VisiSuite.Dal.RelationClasses;
using VNet.VisiSuite.Service.Contact.Message.Base;
using VNet.VisiSuite.Service.Contact.Message.Item;
using VNet.VisiSuite.BusinessLogic.BusinessException;
using VNet.VisiSuite.Common.Logger;
using VNet.VisiSuite.Common.Resource;
using VNet.VisiSuite.Service.Contact.Message;
using VNet.VisiSuite.Common.Helper;

namespace VNet.VisiSuite.BusinessLogic
{
    public class PlantUtil
    {
        private QueryFactory _queryFactory = new QueryFactory();

        public GetDataResponse<IList<PlantItem>> GetPlants(GetDataRequest request)
        {
            using (var adapter = new DataAccessAdapter())
            {
                try
                {
                    var plantQuery = _queryFactory.Plant.WithPath(PlantEntity.PrefetchPathUserLogin, PlantEntity.PrefetchPathUserLogin1)
                                                        .Where(PlantFields.Enabled == true).OrderBy(PlantFields.PlantName.Ascending());
                    EntityCollection<PlantEntity> plantEntities = (EntityCollection<PlantEntity>)adapter.FetchQuery(plantQuery);
                    if (plantEntities == null)
                        return new GetDataResponse<IList<PlantItem>> { Success = false, Error = BusinessLogicError.GetPlantFailed };

                    var areaQuery = _queryFactory.Area.WithPath(AreaEntity.PrefetchPathUserLogin, AreaEntity.PrefetchPathUserLogin1)
                                                      .Where(AreaFields.Enabled == true).AndWhere(AreaFields.PlantId.In(plantEntities.Select(t => t.PlantId).Distinct()));
                    EntityCollection<AreaEntity> areaEntities = (EntityCollection<AreaEntity>)adapter.FetchQuery(areaQuery);
                    if (areaEntities == null)
                        return new GetDataResponse<IList<PlantItem>> { Success = false, Error = BusinessLogicError.GetPlantFailed };

                    var cellQuery = _queryFactory.Cell.WithPath(CellEntity.PrefetchPathUserLogin, CellEntity.PrefetchPathUserLogin1)
                                                 .Where(CellFields.Enabled == true).AndWhere(CellFields.AreaId.In(areaEntities.Select(t => t.AreaId).Distinct()));
                    EntityCollection<CellEntity> cellEntities = (EntityCollection<CellEntity>)adapter.FetchQuery(cellQuery);
                    if (cellEntities == null)
                        return new GetDataResponse<IList<PlantItem>> { Success = false, Error = BusinessLogicError.GetPlantFailed };

                    var result = new List<PlantItem>();
                    foreach (var plantEntity in plantEntities)
                    {
                        var plant = new PlantItem
                        {
                            PlantId = plantEntity.PlantId,
                            Description = plantEntity.Description,
                            Enabled = plantEntity.Enabled,
                            PlantName = plantEntity.PlantName,
                            DateFormat = plantEntity.DateFormat,
                            CreatedBy = string.Format("{0} {1}", plantEntity.UserLogin.FirstName, plantEntity.UserLogin.LastName),
                            LastUpdatedBy = string.Format("{0} {1}", plantEntity.UserLogin1.FirstName, plantEntity.UserLogin1.LastName),
                            CreatedDate = plantEntity.CreatedDate,
                            LastUpdatedDate = plantEntity.LastUpdatedDate,
                            Areas = new List<AreaItem>(),
                        };
                        foreach (var areaEntity in areaEntities.Where(t => t.PlantId == plant.PlantId).OrderBy(t => t.AreaName))
                        {
                            var area = new AreaItem
                            {
                                AreaId = areaEntity.AreaId,
                                PlantId = areaEntity.PlantId,
                                AreaName = areaEntity.AreaName,
                                Description = areaEntity.Description,
                                Enabled = areaEntity.Enabled,
                                CreatedBy = string.Format("{0} {1}", areaEntity.UserLogin.FirstName, areaEntity.UserLogin.LastName),
                                LastUpdatedBy = string.Format("{0} {1}", areaEntity.UserLogin1.FirstName, areaEntity.UserLogin1.LastName),
                                CreatedDate = areaEntity.CreatedDate,
                                LastUpdatedDate = areaEntity.LastUpdatedDate,
                                Cells = new List<CellItem>(),
                            };
                            foreach (var cellEntity in cellEntities.Where(t => t.AreaId == area.AreaId).OrderBy(t => t.CellName))
                            {
                                var cell = new CellItem
                                {
                                    CellId = cellEntity.CellId,
                                    AreaId = cellEntity.AreaId,
                                    CellName = cellEntity.CellName,
                                    Description = cellEntity.Description,
                                    Enabled = cellEntity.Enabled,
                                    VisiCentralGroup = cellEntity.VisiCentralGroup.HasValue ?  cellEntity.VisiCentralGroup.Value : (byte)0,
                                    VisiCentralRow = cellEntity.VisiCentralRow.HasValue ? cellEntity.VisiCentralRow.Value : (byte)0,
                                    VisiCentralColumn = cellEntity.VisiCentralColumn.HasValue ? cellEntity.VisiCentralColumn.Value : (byte)0,
                                    CreatedBy = string.Format("{0} {1}", cellEntity.UserLogin.FirstName, cellEntity.UserLogin.LastName),
                                    LastUpdatedBy = string.Format("{0} {1}", cellEntity.UserLogin1.FirstName, cellEntity.UserLogin1.LastName),
                                    CreatedDate = cellEntity.CreatedDate,
                                    LastUpdatedDate = cellEntity.LastUpdatedDate,
                                };
                                area.Cells.Add(cell);
                            }
                            plant.Areas.Add(area);
                        }
                        result.Add(plant);
                    }

                    return new GetDataResponse<IList<PlantItem>> { Success = true, Data = result };
                }
                catch (Exception ex)
                {
                    FileLog.Error("GetPlants", ex);
                    return new GetDataResponse<IList<PlantItem>> { Success = false, Error = BusinessLogicError.GetPlantFailed };
                }
            }
        }

        public SaveDataResponse<IList<PlantItem>> UpdatePlants(SavePlantRequest request)
        {
            using (var adapter = new DataAccessAdapter())
            {
                try
                {
                    adapter.StartTransaction(IsolationLevel.ReadCommitted, "UpdatePlantTransaction");
                    RelationPredicateBucket filterBucket;
                    int result;
                    EntityCollection<CellEntity> cells;
                    EntityCollection<PlantEntity> plants;
                    EntityCollection<AreaEntity> areas;

                    if (request.Cells != null)
                    {
                        #region Delete Cells
                        //Check production data associated with the object
                        var deletedCellIds = request.Cells.Where(t => t.IsDeleted).Select(t => t.CellId);
                        if (deletedCellIds.Count() > 0)
                        {
                            var query = _queryFactory.Create()
                                        .Select(CellFields.CellName, Functions.CountRow().As("CellShiftCount"))
                                        .From(_queryFactory.Cell.InnerJoin(_queryFactory.CellShift).On(CellFields.CellId == CellShiftFields.CellId))
                                        .Where(CellFields.CellId.In(deletedCellIds))
                                        .GroupBy(CellFields.CellName);

                            var dataTable = adapter.FetchAsDataTable(query);
                            if (dataTable == null)
                                throw new Exception();

                            Dictionary<string, int> errorCells = new Dictionary<string, int>();
                            foreach (DataRow r in dataTable.Rows)
                            {
                                var value = Int32.Parse(r["CellShiftCount"].ToString());
                                var key = r["CellName"].ToString();
                                errorCells.Add(key, value);
                            }

                            //If there is any production data, return error
                            if (errorCells.Count() > 0)
                            {
                                var cellNames = string.Empty;
                                foreach (var key in errorCells.Keys)
                                    if (errorCells[key] > 0)
                                        cellNames += string.Format("{0}, ", key);

                                cellNames = cellNames.Trim().Trim(',');

                                adapter.Rollback();
                                return new SaveDataResponse<IList<PlantItem>> { Success = false, Error = new ServiceError { Description = string.Format(FormatString.CannotDeleteItem, "cell", cellNames), }, };
                            }

                            //Continues to delete
                            cells = new EntityCollection<CellEntity>();
                            var includedFields = new ExcludeIncludeFieldsList(false) { CellFields.CellId };
                            filterBucket = new RelationPredicateBucket(CellFields.CellId.In(deletedCellIds));
                            adapter.FetchEntityCollection(cells, includedFields, filterBucket);

                            result = adapter.DeleteEntityCollection(cells);
                            if (result != cells.Count())
                                throw new Exception();
                        }
                        #endregion

                        #region Update Cells

                        var editCellIds = request.Cells.Where(t => !t.IsDeleted).Select(t => t.CellId);
                        if (editCellIds.Count() > 0)
                        {
                            cells = new EntityCollection<CellEntity>();
                            filterBucket = new RelationPredicateBucket(CellFields.CellId.In(editCellIds));
                            adapter.FetchEntityCollection(cells, filterBucket);
                            var now = DateTime.UtcNow;
                            foreach (var updateCell in cells)
                            {
                                var item = request.Cells.FirstOrDefault(t => t.CellId == updateCell.CellId);
                                if (item != null)
                                {
                                    updateCell.LastUpdatedBy = request.Identity.UserLoginId;
                                    updateCell.LastUpdatedDate = now;
                                    updateCell.CellName = item.CellName;
                                    updateCell.Description = item.Description;
                                    updateCell.Enabled = item.Enabled;
                                    if (!string.IsNullOrWhiteSpace(item.Password))
                                        updateCell.Password = EncryptionHelper.EncodePassword(item.Password);
                                }
                            }
                            result = adapter.SaveEntityCollection(cells);
                            if (result != cells.Count())
                                throw new Exception();
                        }
                        #endregion
                    }

                    if (request.Areas != null)
                    {
                        #region Delete Areas
                        //Check production data associated with the object
                        var deletedAreaIds = request.Areas.Where(t => t.IsDeleted).Select(t => t.AreaId);
                        if (deletedAreaIds.Count() > 0)
                        {
                            var query = _queryFactory.Create()
                                        .Select(AreaFields.AreaName, Functions.CountRow().As("CellShiftCount"))
                                        .From(_queryFactory.Area.InnerJoin(_queryFactory.Cell).On(AreaFields.AreaId == CellFields.AreaId)
                                                                .InnerJoin(_queryFactory.CellShift).On(CellFields.CellId == CellShiftFields.CellId))
                                        .Where(AreaFields.AreaId.In(deletedAreaIds))
                                        .GroupBy(AreaFields.AreaName);

                            var dataTable = adapter.FetchAsDataTable(query);
                            if (dataTable == null)
                                throw new Exception();

                            Dictionary<string, int> errorAreas = new Dictionary<string, int>();
                            foreach (DataRow r in dataTable.Rows)
                            {
                                var value = Int32.Parse(r["CellShiftCount"].ToString());
                                var key = r["AreaName"].ToString();
                                errorAreas.Add(key, value);
                            }

                            //If there is any production data, return error
                            if (errorAreas.Count() > 0)
                            {
                                var areaNames = string.Empty;
                                foreach (var key in errorAreas.Keys)
                                    if (errorAreas[key] > 0)
                                        areaNames += string.Format("{0}, ", key);

                                areaNames = areaNames.Trim().Trim(',');

                                adapter.Rollback();
                                return new SaveDataResponse<IList<PlantItem>> { Success = false, Error = new ServiceError { Description = string.Format(FormatString.CannotDeleteItem, "area", areaNames), }, };
                            }

                            //Continues to delete
                            areas = new EntityCollection<AreaEntity>();
                            var includedFields = new ExcludeIncludeFieldsList(false) { AreaFields.AreaId };
                            filterBucket = new RelationPredicateBucket(AreaFields.AreaId.In(deletedAreaIds));
                            adapter.FetchEntityCollection(areas, includedFields, filterBucket);

                            cells = new EntityCollection<CellEntity>();
                            includedFields = new ExcludeIncludeFieldsList(false) { CellFields.CellId };
                            filterBucket = new RelationPredicateBucket(CellFields.AreaId.In(areas.Select(t => t.AreaId)));
                            adapter.FetchEntityCollection(cells, includedFields, filterBucket);

                            result = adapter.DeleteEntityCollection(cells);
                            if (result != cells.Count())
                                throw new Exception();

                            result = adapter.DeleteEntityCollection(areas);
                            if (result != areas.Count())
                                throw new Exception();
                        }
                        #endregion

                        #region Update Areas

                        var editAreaIds = request.Areas.Where(t => !t.IsDeleted).Select(t => t.AreaId);
                        if (editAreaIds.Count() > 0)
                        {
                            areas = new EntityCollection<AreaEntity>();
                            filterBucket = new RelationPredicateBucket(AreaFields.AreaId.In(editAreaIds));
                            adapter.FetchEntityCollection(areas, filterBucket);
                            var now = DateTime.UtcNow;
                            foreach (var updateArea in areas)
                            {
                                var item = request.Areas.FirstOrDefault(t => t.AreaId == updateArea.AreaId);
                                if (item != null)
                                {
                                    updateArea.LastUpdatedBy = request.Identity.UserLoginId;
                                    updateArea.LastUpdatedDate = now;
                                    updateArea.AreaName = item.AreaName;
                                    updateArea.Description = item.Description;
                                    updateArea.Enabled = item.Enabled;
                                }
                            }
                            result = adapter.SaveEntityCollection(areas);
                            if (result != areas.Count())
                                throw new Exception();
                        }
                        #endregion
                    }

                    if (request.Plants != null)
                    {
                        #region Delete Plants
                        //Check production data associated with the object
                        var deletedPlantIds = request.Plants.Where(t => t.IsDeleted).Select(t => t.PlantId);
                        if (deletedPlantIds.Count() > 0)
                        {
                            var query = _queryFactory.Create()
                                        .Select(PlantFields.PlantName, Functions.CountRow().As("CellShiftCount"))
                                        .From(_queryFactory.Plant.InnerJoin(_queryFactory.Area).On(PlantFields.PlantId == AreaFields.PlantId)
                                                                 .InnerJoin(_queryFactory.Cell).On(AreaFields.AreaId == CellFields.AreaId)
                                                                 .InnerJoin(_queryFactory.CellShift).On(CellFields.CellId == CellShiftFields.CellId))
                                        .Where(PlantFields.PlantId.In(deletedPlantIds))
                                        .GroupBy(PlantFields.PlantName);

                            var dataTable = adapter.FetchAsDataTable(query);
                            if (dataTable == null)
                                throw new Exception();

                            Dictionary<string, int> errorPlants = new Dictionary<string, int>();
                            foreach (DataRow r in dataTable.Rows)
                            {
                                var value = Int32.Parse(r["CellShiftCount"].ToString());
                                var key = r["PlantName"].ToString();
                                errorPlants.Add(key, value);
                            }

                            //If there is any production data, return error
                            if (errorPlants.Count() > 0)
                            {
                                var plantNames = string.Empty;
                                foreach (var key in errorPlants.Keys)
                                    if (errorPlants[key] > 0)
                                        plantNames += string.Format("{0}, ", key);

                                plantNames = plantNames.Trim().Trim(',');

                                adapter.Rollback();
                                return new SaveDataResponse<IList<PlantItem>> { Success = false, Error = new ServiceError { Description = string.Format(FormatString.CannotDeleteItem, "plant", plantNames), }, };
                            }

                            //Continues to delete
                            plants = new EntityCollection<PlantEntity>();
                            var includedFields = new ExcludeIncludeFieldsList(false) { PlantFields.PlantId };
                            filterBucket = new RelationPredicateBucket(PlantFields.PlantId.In(deletedPlantIds));
                            adapter.FetchEntityCollection(plants, includedFields, filterBucket);

                            areas = new EntityCollection<AreaEntity>();
                            includedFields = new ExcludeIncludeFieldsList(false) { AreaFields.AreaId };
                            filterBucket = new RelationPredicateBucket(AreaFields.PlantId.In(deletedPlantIds));
                            adapter.FetchEntityCollection(areas, includedFields, filterBucket);

                            cells = new EntityCollection<CellEntity>();
                            includedFields = new ExcludeIncludeFieldsList(false) { CellFields.CellId };
                            filterBucket = new RelationPredicateBucket(CellFields.AreaId.In(areas.Select(t => t.AreaId)));
                            adapter.FetchEntityCollection(cells, includedFields, filterBucket);

                            result = adapter.DeleteEntityCollection(cells);
                            if (result != cells.Count())
                                throw new Exception();

                            result = adapter.DeleteEntityCollection(areas);
                            if (result != areas.Count())
                                throw new Exception();

                            result = adapter.DeleteEntityCollection(plants);
                            if (result != plants.Count())
                                throw new Exception();
                        }
                        #endregion

                        #region Update Plants

                        var editPlantIds = request.Plants.Where(t => !t.IsDeleted).Select(t => t.PlantId);
                        if (editPlantIds.Count() > 0)
                        {
                            plants = new EntityCollection<PlantEntity>();
                            filterBucket = new RelationPredicateBucket(PlantFields.PlantId.In(editPlantIds));
                            adapter.FetchEntityCollection(plants, filterBucket);
                            var now = DateTime.UtcNow;
                            foreach (var updatePlant in plants)
                            {
                                var item = request.Plants.FirstOrDefault(t => t.PlantId == updatePlant.PlantId);
                                if (item != null)
                                {
                                    updatePlant.LastUpdatedBy = request.Identity.UserLoginId;
                                    updatePlant.LastUpdatedDate = now;
                                    updatePlant.PlantName = item.PlantName;
                                    updatePlant.Description = item.Description;
                                    updatePlant.Enabled = item.Enabled;
                                }
                            }
                            result = adapter.SaveEntityCollection(plants);
                            if (result != plants.Count())
                                throw new Exception();
                        }
                        #endregion
                    }

                    adapter.Commit();
                }
                catch
                {
                    adapter.Rollback();
                    return new SaveDataResponse<IList<PlantItem>> { Success = false, Error = BusinessLogicError.UpdatePlantFailed };
                }

                var response = GetPlants(new GetDataRequest());
                return new SaveDataResponse<IList<PlantItem>> { Success = response.Success, Data = response.Data, };
            }
        }

        public SaveDataResponse<PlantItem> UpdatePlant(SaveDataRequest<PlantItem> request)
        {
            using (var adapter = new DataAccessAdapter())
            {
                try
                {
                    var errorMessage = string.Empty;
                    if (!string.IsNullOrEmpty(errorMessage = CheckPlantNameUnique(adapter, request.Data)))
                        return new SaveDataResponse<PlantItem> { Success = false, Error = new ServiceError { Description = errorMessage, }, };

                    var plantQuery = _queryFactory.Plant.Where(PlantFields.PlantId == request.Data.PlantId);
                    var plantEntity = adapter.FetchFirst(plantQuery);
                    if (plantEntity == null)
                        return new SaveDataResponse<PlantItem> { Success = false, Error = BusinessLogicError.PlantDoesNotExist };

                    plantEntity.LastUpdatedBy = request.Identity.UserLoginId;
                    plantEntity.LastUpdatedDate = DateTime.UtcNow;
                    plantEntity.PlantName = request.Data.PlantName;
                    plantEntity.Description = request.Data.Description;
                    plantEntity.DateFormat = request.Data.DateFormat;
                    plantEntity.Enabled = request.Data.Enabled;

                    if (!adapter.SaveEntity(plantEntity))
                        return new SaveDataResponse<PlantItem> { Success = false, Error = BusinessLogicError.UpdatePlantFailed };

                    // Get plant entity after updated
                    var q = _queryFactory.Create()
                        .Select(() => new
                        {
                            Description = PlantFields.Description.Source("p").ToValue<string>(),
                            Enabled = PlantFields.Enabled.Source("p").ToValue<Boolean>(),
                            PlantName = PlantFields.PlantName.Source("p").ToValue<string>(),
                            DateFormat = PlantFields.DateFormat.Source("p").ToValue<string>(),
                            LastUpdatedDate = PlantFields.LastUpdatedDate.Source("p").ToValue<DateTime>(),
                            PlantId = PlantFields.PlantId.Source("p").ToValue<int>(),
                            FirstName1 = (UserLoginFields.FirstName.Source("u").SetFieldAlias("FistName1")).ToValue<string>(),
                            LastName1 = (UserLoginFields.LastName.Source("u").SetFieldAlias("LastName1")).ToValue<string>(),
                        })
                        .From(_queryFactory.Plant.As("p").InnerJoin(PlantEntity.Relations.UserLoginEntityUsingLastUpdatedBy, "p", "u"))
                        .Where(PlantFields.PlantId.Source("p") == request.Data.PlantId);

                    var val = adapter.FetchQuery(q).FirstOrDefault();
                    if (val == null)
                        return new SaveDataResponse<PlantItem> { Success = false, Error = BusinessLogicError.UpdatePlantFailed };

                    return new SaveDataResponse<PlantItem>
                    {
                        Success = true,
                        Data = new PlantItem
                        {
                            Description = val.Description,
                            PlantName = val.PlantName,
                            DateFormat = val.DateFormat,
                            Enabled = val.Enabled,
                            PlantId = val.PlantId,
                            LastUpdatedBy = string.Format(FormatString.NameFormat, val.FirstName1, val.LastName1),
                            LastUpdatedDate = val.LastUpdatedDate,
                        }
                    };
                }
                catch (Exception ex)
                {
                    FileLog.Error("UpdatePlant", ex);
                    return new SaveDataResponse<PlantItem> { Success = false, Error = BusinessLogicError.UpdatePlantFailed };
                }
            }


        }

        public SaveDataResponse<PlantItem> InsertPlant(SaveDataRequest<PlantItem> request)
        {
            using (var adapter = new DataAccessAdapter())
            {
                try
                {
                    //Check overlap
                    string errorMessage = null;
                    if (!string.IsNullOrEmpty(errorMessage = CheckPlantNameUnique(adapter, request.Data)))
                        return new SaveDataResponse<PlantItem> { Success = false, Error = new ServiceError { Description = errorMessage, }, };

                    var plantEntity = new PlantEntity();
                    var now = DateTime.UtcNow;
                    plantEntity.Description = request.Data.Description;
                    plantEntity.PlantName = request.Data.PlantName;
                    plantEntity.Enabled = request.Data.Enabled;
                    plantEntity.DateFormat = request.Data.DateFormat;
                    plantEntity.CreatedDate = now;
                    plantEntity.CreatedBy = request.Identity.UserLoginId;
                    plantEntity.LastUpdatedDate = now;
                    plantEntity.LastUpdatedBy = request.Identity.UserLoginId;

                    if (!adapter.SaveEntity(plantEntity, true))
                        return new SaveDataResponse<PlantItem> { Success = false, Error = BusinessLogicError.InsertPlantFailed };

                    // Get plant entity after updated
                    var q = _queryFactory.Create()
                        .Select(() => new
                        {
                            Description = PlantFields.Description.Source("p").ToValue<string>(),
                            PlantName = PlantFields.PlantName.Source("p").ToValue<string>(),
                            DateFormat = PlantFields.DateFormat.Source("p").ToValue<string>(),
                            Enabled = PlantFields.Enabled.Source("p").ToValue<Boolean>(),
                            LastUpdatedDate = PlantFields.LastUpdatedDate.Source("p").ToValue<DateTime>(),
                            PlantId = PlantFields.PlantId.Source("p").ToValue<int>(),
                            FirstName1 = (UserLoginFields.FirstName.Source("u").SetFieldAlias("FistName1")).ToValue<string>(),
                            LastName1 = (UserLoginFields.LastName.Source("u").SetFieldAlias("LastName1")).ToValue<string>(),
                        })
                        .From(_queryFactory.Plant.As("p").InnerJoin(PlantEntity.Relations.UserLoginEntityUsingLastUpdatedBy, "p", "u"))
                        .Where(PlantFields.PlantId.Source("p") == plantEntity.PlantId);

                    var val = adapter.FetchQuery(q).FirstOrDefault();
                    if (val == null)
                        return new SaveDataResponse<PlantItem> { Success = false, Error = BusinessLogicError.InsertPlantFailed };

                    return new SaveDataResponse<PlantItem>
                    {
                        Success = true,
                        Data = new PlantItem
                        {
                            Description = val.Description,
                            PlantName = val.PlantName,
                            DateFormat = val.DateFormat,
                            Enabled = val.Enabled,
                            PlantId = val.PlantId,
                            CreatedBy = string.Format(FormatString.NameFormat, val.FirstName1, val.LastName1),
                            CreatedDate = val.LastUpdatedDate,
                            LastUpdatedBy = string.Format(FormatString.NameFormat, val.FirstName1, val.LastName1),
                            LastUpdatedDate = val.LastUpdatedDate,
                        }
                    };
                }
                catch (Exception ex)
                {
                    FileLog.Error("InsertPlant", ex);
                    return new SaveDataResponse<PlantItem> { Success = false, Error = BusinessLogicError.InsertPlantFailed };
                }
            }
        }

        public DeleteDataResponse DeletePlant(DeleteDataRequest request)
        {
            using (var adapter = new DataAccessAdapter())
            {
                try
                {
                    var query = _queryFactory.Create()
                                         .Select(CellShiftFields.CellShiftId)
                                         .From(_queryFactory.Area.InnerJoin(_queryFactory.Cell).On(AreaFields.AreaId == CellFields.AreaId)
                                                                 .InnerJoin(_queryFactory.CellShift).On(CellFields.CellId == CellShiftFields.CellId))
                                         .Where(AreaFields.PlantId == request.DataId);

                    var dataTable = adapter.FetchAsDataTable(query);
                    if (dataTable == null)
                        return new DeleteDataResponse { Success = false, Error = BusinessLogicError.DeletePlantFailed };

                    if (dataTable.Rows.Count > 0)
                        return new DeleteDataResponse { Success = false, Error = new ServiceError { Description = string.Format(FormatString.CannotDeleteItem2, "plant") }, };

                    var query2 = _queryFactory.Plant.Where(PlantFields.PlantId == request.DataId);
                    var plantEntity = adapter.FetchFirst(query2);
                    if (plantEntity == null)
                        return new DeleteDataResponse { Error = BusinessLogicError.PlantDoesNotExist, Success = false };

                    if (!adapter.DeleteEntity(plantEntity))
                        return new DeleteDataResponse { Error = BusinessLogicError.DeletePlantFailed, Success = false };

                    return new DeleteDataResponse { Success = true, DataId = request.DataId };
                }
                catch
                {
                    return new DeleteDataResponse { Success = false, Error = BusinessLogicError.DeletePlantFailed };
                }
            }
        }

        private string CheckPlantNameUnique(DataAccessAdapter adapter, PlantItem data)
        {
            var query = _queryFactory.Plant.Where(PlantFields.Enabled == true & PlantFields.PlantName == data.PlantName & PlantFields.PlantId != data.PlantId);
            var plants = (EntityCollection<PlantEntity>)adapter.FetchQuery(query);

            if (plants != null && plants.Count > 0)
                return ErrorMessages.ExistedPlantName;
            return null;
        }
    }
}
